package com.rjhch.tonglink;

import com.rjhch.tonglink.Constants.Enums.MsgType;
import com.tongtech.tlq.base.*;
import com.tongtech.tmqi.util.FileUtil;

import java.io.File;
import java.util.UUID;

/**
 * @author zhangwenhao
 */
public class BaseUtils {
    private static TlqConnection tlqConnection = null;
    private static TlqQCU tlqQcu = null;


    public static boolean sendMsg(TlqConnContext connContext, String QName, MsgType msgType, String FileName, String msg)
            throws Exception {
        return sendMsg(connContext, null, QName, msgType, FileName, msg);
    }


    public static boolean sendMsg(String QcuName, String QName, MsgType msgType, String FileName, String msg)
            throws Exception {
        return sendMsg(null, QcuName, QName, msgType, FileName, msg);
    }

    private static boolean sendMsg(TlqConnContext connContext, String QcuName, String QName, MsgType msgType,
                                   String FileName, String msg) throws Exception {
        initConnect(connContext, QcuName);
        if (msgType.equals(MsgType.BUFFER)) {
            sendBuffMsg(msg, QName);
        } else {
            sendFileMsg(FileName, QName);
        }
        Dealloc(tlqConnection, tlqQcu);
        return true;
    }

    private static void sendBuffMsg(String msg, String QName) throws TlqException {
        TlqMessage msgInfo = new TlqMessage();
        TlqMsgOpt msgOpt = new TlqMsgOpt();
        msgInfo.MsgType = TlqMessage.BUF_MSG;
        msgInfo.MsgSize = msg.length();
        byte[] msgContent = msg.getBytes();
        msgInfo.setMsgData(msgContent);

        msgInfo.Persistence = TlqMessage.TLQPER_Y;
        msgInfo.Priority = TlqMessage.TLQPRI_NORMAL;
        msgInfo.Expiry = 1000;
        msgOpt.QueName = QName;

        tlqQcu.putMessage(msgInfo, msgOpt);
    }

    private static synchronized String createID() {
        return UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
    }

    private static void sendFileMsg(String myFileName, String QName) throws TlqException {
        TlqMessage msgInfo = new TlqMessage();
        TlqMsgOpt msgOpt = new TlqMsgOpt();
        File file = new File(myFileName);
        String fName = myFileName;
        if (file.isAbsolute()) {
            fName = myFileName + " " + createID() + "_" + file.getName();
        } else {
            int pos = file.getPath().lastIndexOf(File.separator);
            String startStr = file.getPath().substring(0, pos + 1);
            String endStr = file.getPath().substring(pos + 1);
            fName = myFileName + " " + startStr + createID() + "_" + endStr;
        }
        System.out.println(fName);
        msgInfo.MsgType = TlqMessage.FILE_MSG;
        msgInfo.FileSize = file.length() + "";
        msgInfo.setMsgData(fName.getBytes());
        msgOpt.RemoveFileFlag = TlqMsgOpt.NOTREMOVEFILE;

        msgInfo.Persistence = TlqMessage.TLQPER_Y;
        msgInfo.Priority = TlqMessage.TLQPRI_NORMAL;
        msgInfo.Expiry = 1000;
        msgOpt.QueName = QName;

        tlqQcu.putMessage(msgInfo, msgOpt);
    }

    public static void GetMsg(TlqConnContext conncontext, String QueName, int WaitInterval, MsgHandle hand, File filePath)
            throws Exception {
        GetMsg(conncontext, null, QueName, WaitInterval, hand, filePath);
    }

    public static void GetMsg(String QcuName, String QueName, int WaitInterval, MsgHandle hand, File filePath) throws Exception {
        GetMsg(null, QcuName, QueName, WaitInterval, hand, filePath);
    }

    private static void GetMsg(TlqConnContext conncontext, String QcuName, String QueName, int WaitInterval,
                               MsgHandle hand, File filePath) throws Exception {
        initConnect(conncontext, QcuName);
        int msgCount = 0;
        try {
            while (true) {
                TlqMessage msgInfo = new TlqMessage();
                TlqMsgOpt msgOpt = new TlqMsgOpt();

                msgOpt.QueName = QueName;
                msgOpt.WaitInterval = WaitInterval;
                msgOpt.OperateType = TlqMsgOpt.TLQOT_GET;

                tlqQcu.getMessage(msgInfo, msgOpt);
                if (!filePath.exists()) {
                    filePath.mkdirs();
                }
                String fileName = new String(msgInfo.getMsgData());
                File file = new File(fileName);
                FileUtil.copyFile(file, new File(filePath, fileName.substring(1)));
                try {
                    file.delete();
                } catch (Exception e) {
                }
                msgCount = msgCount + 1;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        hand.dealMsg(msgInfo);
                    }
                }).start();
                if (msgOpt.AckMode == TlqMsgOpt.TLQACK_USER) {
                    int acktype = TlqMsgOpt.TLQACK_COMMIT;
                    tlqQcu.ackMessage(msgInfo, msgOpt, acktype);
                }
            }
        } catch (TlqException e) {
            System.out.println("" + msgCount + "");
            // e.printStackTrace();
        } finally {
            Dealloc(tlqConnection, tlqQcu);
        }
    }

    public static void delMsg(TlqConnContext conncontext, String QueName)
            throws Exception {
        delMsg(null, null, QueName);
    }


    public static void delMsg(String QcuName, String QueName) throws Exception {
        delMsg(null, QcuName, QueName);
    }

    private static void delMsg(TlqConnContext conncontext, String QcuName, String QueName) throws Exception {
        initConnect(conncontext, QcuName);
        try {
            TlqMessage msgInfo = new TlqMessage();
            TlqMsgOpt msgOpt = new TlqMsgOpt();

            msgOpt.QueName = QcuName;
            /* msgOpt.MatchOption = TlqMsgOpt.TLQMATCH_PRIORITY;
             msgInfo.Priority = 5;*/
            msgOpt.DelState = TlqMsgOpt.TLQSTATE_ALL;

            int num = tlqQcu.delMessage(msgInfo, msgOpt);

            System.out.println("----------- " + num + " ---------");
        } catch (TlqException e) {
            e.printStackTrace();
        } finally {
            Dealloc(tlqConnection, tlqQcu);
        }
    }


    public static boolean PubMag(TlqConnContext conncontext, String Topic, String msg, int CancelpubFlag)
            throws TlqException {
        return PubMag(conncontext, null, Topic, msg, CancelpubFlag);
    }

    public static boolean PubMag(String QcuName, String Topic, String msg, int CancelpubFlag) throws TlqException {
        return PubMag(null, QcuName, Topic, msg, CancelpubFlag);
    }

    private static boolean PubMag(TlqConnContext conncontext, String QcuName, String Topic, String msg,
                                  int CancelpubFlag) throws TlqException {
        initConnect(conncontext, QcuName);
        TlqMessage msgInfo = new TlqMessage();
        TlqMsgOpt msgOpt = new TlqMsgOpt();
        msgInfo.MsgSize = msg.length();
        byte[] msgContent = msg.getBytes();
        msgInfo.setMsgData(msgContent);
        msgInfo.Persistence = TlqMessage.TLQPER_Y;
        msgInfo.Priority = TlqMessage.TLQPRI_NORMAL;
        msgInfo.Expiry = -1;
        msgOpt.OperateType = TlqMsgOpt.TLQOT_PUB;
        msgOpt.PubSubScope = TlqMsgOpt.TLQPSS_GLOBAL | TlqMsgOpt.TLQPSS_LOCAL;
        msgOpt.QueName = "TLQ.SYS.BROKER.SYN";
        msgOpt.Topic = Topic;

        if (CancelpubFlag == 0) {
            tlqQcu.putMessage(msgInfo, msgOpt);
        } else if (CancelpubFlag == 1) {
            msgOpt.OperateType = TlqMsgOpt.TLQOT_DELPUB;
            String CorrMsgId = createID();
            msgInfo.CorrMsgId = CorrMsgId.getBytes();
            tlqQcu.putMessage(msgInfo, msgOpt);
        }

        Dealloc(tlqConnection, tlqQcu);
        return true;
    }

    public static boolean SubMsg(TlqConnContext conncontext, String Topic, int CancelpubFlag) throws Exception {
        return SubMsg(conncontext, null, Topic, CancelpubFlag);
    }

    public static boolean SubMsg(String QcuName, String Topic, int CancelpubFlag) throws Exception {
        return SubMsg(null, QcuName, Topic, CancelpubFlag);
    }

    private static boolean SubMsg(TlqConnContext conncontext, String QcuName, String Topic, int CancelpubFlag)
            throws Exception {
        initConnect(conncontext, QcuName);
        TlqMessage msgInfo = new TlqMessage();
        TlqMsgOpt msgOpt = new TlqMsgOpt();
        msgInfo.MsgSize = 10;
        msgInfo.Persistence = TlqMessage.TLQPER_Y;
        msgInfo.Priority = TlqMessage.TLQPRI_NORMAL;
        msgInfo.Expiry = -1;
        msgOpt.OperateType = TlqMsgOpt.TLQOT_SUB;
        msgOpt.PubSubScope = TlqMsgOpt.TLQPSS_GLOBAL | TlqMsgOpt.TLQPSS_LOCAL;
        msgOpt.Topic = Topic;
        if (CancelpubFlag == 0) {
            tlqQcu.putMessage(msgInfo, msgOpt);
        } else if (CancelpubFlag == 1) {
            msgOpt.OperateType = TlqMsgOpt.TLQOT_DELSUB;
            String CorrMsgId = createID();
            msgInfo.CorrMsgId = CorrMsgId.getBytes();
            tlqQcu.putMessage(msgInfo, msgOpt);
        }
        Dealloc(tlqConnection, tlqQcu);
        return true;

    }


    private static void initConnect(TlqConnContext conncontext, String QcuName) throws TlqException {
        if (conncontext != null) {
            tlqConnection = new TlqConnection(conncontext);
        } else {
            tlqConnection = new TlqConnection();
        }
        if (QcuName != null) {
            tlqQcu = tlqConnection.openQCU(QcuName);
        } else {
            tlqQcu = tlqConnection.openQCU();
        }
    }

    public static void Dealloc(TlqConnection tlqConnection, TlqQCU tlqQcu) {
        if (tlqQcu != null) {
            try {
                tlqQcu.close();
            } catch (TlqException e) {
                e.printStackTrace();
            }
        }
        if (tlqConnection != null) {
            try {
                tlqConnection.close();
            } catch (TlqException e) {
                e.printStackTrace();
            }
        }
    }

    public static TlqConnContext getContext(String host, int port) {
        return new TlqConnContext(host, port);
    }
}
